package gdr.dev;

import gdr.battle.core.BattleContainer;
import gdr.player.DefaultPlayer;
import gdr.player.Statistiche;
import gdr.action.descriptor.*;

public class Formula {
	
	/**
	 * Esperienza necessaria a raggiungere il livello successivo
	 * @return
	 */
	public static long expToNextLevel(int level, long m1, long q1, long lim1, long m2, long lim2, long m3)
	{	long q2 = m1 * lim1 + q1;
		long q3 = m2* (lim2-lim1) + q2;
		if (level <= lim1)
			return m1 * level + q1;
		if (level <= lim2)
			return m2 * (level-lim1) + q2;
		return m3 * (level - lim2) + q3;
	}
	
	/**
	 * Calcola il valore di una statistica
	 * @return
	 */
	public static long getStat(int stat, int level, long baseStat, long incStat, long bonusFisico, long bonusMagico){
		double inc = ((double)incStat)/100;
		long bonus = 0;
		switch (stat){
			case Statistiche.HP:
				bonus = (bonusFisico + bonusMagico)/20;
			case Statistiche.ATK:
				bonus = bonusFisico/10;
				break;
			case Statistiche.MAG:
				bonus = bonusMagico /40;
				break;
			case Statistiche.MP:
				bonus = bonusMagico/15;
				break;
		}
		return (long)(baseStat*(1+inc*level)) + bonus;
	}
	

	public static long getMove(BattleContainer container, DefaultPlayer player){
		return player.getMove();
	}
	
	/**
	 * Calcola il raggio di una magia
	 * @param esperienzaMagica
	 * @return
	 */
	public static int getRaggioMagie(long esperienzaMagica){
		if (esperienzaMagica<40) return 1;
		if (esperienzaMagica<300) return 2;
		return 3;
	}
	
	/**
	 * Calcola il danno di un attacco fisico
	 * @return
	 */
	public static long dannoAttaccoFisico(BattleContainer container, DefaultPlayer source, DefaultPlayer dest){
		try{long atk = source.getMaxStat(Statistiche.ATK);
			long def = dest.getMaxStat(Statistiche.DEF);
			double damage = Util.random(0.95, 1.05)*atk * (1* atk + 100) /(3 * def + 500); 
			return (long)damage;
		}catch(Exception e){
			return 0;
		}
	}
	
	/**
	 * Calcola il danno di un attacco magico
	 * @return
	 */
	public static long dannoAttaccoMagico(BattleContainer container, DefaultPlayer source, DefaultPlayer dest, int potenza){
		try{
			long mag = source.getMaxStat(Statistiche.MAG);
			long res = dest.getMaxStat(Statistiche.RES);
			double damage = Util.random(0.95, 1.05) * mag * potenza/170 * (1* mag + 100) /(3 * res + 500); 
			return Math.max((long)damage,0);
		}catch(Exception e){
			return 0;
		}
	}
	
	/**
	 * Calcola gli HP che un personaggio recupera usando la magia Heal
	 * @return
	 */
	public static long recuperoHeal(BattleContainer container, DefaultPlayer source, DefaultPlayer dest, int potenza){
		try{
			long mag = source.getMaxStat(Statistiche.MAG);
			long res = dest.getMaxStat(Statistiche.RES);
			double damage = Util.random(0.95, 1.05) * mag * potenza/170 * (1* mag + 100) /(3 * res + 500); 
			return Math.max((long)damage,0);
		}catch(Exception e){
			return 0;
		}
	}

	public static long costoMPMagia(BattleContainer container, DefaultPlayer source, Magic magia){
		switch (magia.getLivelloMagia()){
		case BASE:
				return 4;
		case INTERMEDIO:
				return 10;
		case AVANZATO:
				return 25;
		}
		return 0;
	}
	
	public static long costoMPSummon(BattleContainer container, DefaultPlayer source, Summon summon){
		return summon.getCostoMP();
	}
	
}
